package com.example.zwx.myapplication;

import android.app.Service;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothGatt;
import android.bluetooth.BluetoothGattCallback;
import android.bluetooth.BluetoothGattCharacteristic;
import android.bluetooth.BluetoothGattDescriptor;
import android.bluetooth.BluetoothGattService;
import android.bluetooth.BluetoothManager;
import android.bluetooth.BluetoothProfile;
import android.content.Context;
import android.content.Intent;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.Messenger;
import android.os.RemoteException;

import com.example.zwx.myapplication.utils.IrParser;
import com.example.zwx.myapplication.utils.L;

import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.UUID;


public class BleServiceV2 extends Service {


    //constants
    public static final String TAG = "BleService";

    //private static final int REQUEST_ENABLE_BT = 0x1;

    public static final int MSG_SERVICE_CONNECTED = 10;//服务绑定成功
    public static final int MSG_CONNECT2_BLE_DEVICE = 12;//连接到设备
    public static final int MSG_SEND_IR_DATA = 13;//发送红外数据
    public static final int MSG_4 = 14;

    public static final int MSG_DEVICE_CONNECTION_RESULT = 15;//设备连接结果
    public static final int MSG_IR_SEND_FEEDBACK = 16;//蓝牙发送结果

    public static final int MSG_GATT_SERVICE_DISCOVERD = 17;//找到服务

    public static final int MSG_GATT_CONNECTED = 18;//GATT断开连接

    public static final int MSG_GATT_DISCONNECTED = 19;//GATT断开连接

    private static final int STATE_DISCONNECTED = 0;
    private static final int STATE_CONNECTING = 1;
    private static final int STATE_CONNECTED = 2;

    private static String BUZZER_SERVICE = "00001802-0000-1000-8000-00805f9b34fb";
    private static String BUZZER_CHARACTER = "00002a06-0000-1000-8000-00805f9b34fb";
    private static final UUID UUID_BUZZER_SERVICE;
    private static final UUID UUID_BUZZER_CHARACTER;
    private static String HID_SERVICE;
    private static final UUID UUID_HID_SERVICE;

    //ble stuffs


    private BluetoothAdapter mBluetoothAdapter;
    private BluetoothGatt mBluetoothGatt;
    private BluetoothDevice mBluetoothDevice;

    private BluetoothGattCharacteristic mVendorOutCharacteristic;
    private BluetoothGattCharacteristic mVendorInCharacteristic;
    private BluetoothGattCharacteristic mIrOutCharacteristic;
    private BluetoothGattCharacteristic mIrInCharacteristic;
    private BluetoothGattCharacteristic mBuzzerCharacteristic;
    private BluetoothGattCharacteristic mOtaInCharacteristic;
    private BluetoothGattCharacteristic mKeyInCharacteristic;

    private String mBluetoothDeviceAddress;
    private String mDeviceName;
    private String mDeviceAddr;
    private int mConnectionState = STATE_DISCONNECTED;


    //the Messengers stuff
    private ServiceHandler mHandler;
    private Messenger mServiceMessenger;
    private Messenger mClientMessenger;
    private Context mAppContext;

    /**
     * copied
     */
    private IrLossyCompression mIrLossyCompression;

    private byte[] mIrSendBuff = null;

    private boolean mIrPacketSendOk = false;
    private boolean mIrPacketRecOk = false;

    private int mSendedPacketNum = 0;


    static {
        UUID_BUZZER_SERVICE = UUID.fromString(BUZZER_SERVICE);
        UUID_BUZZER_CHARACTER = UUID.fromString(BUZZER_CHARACTER);
        HID_SERVICE = "00001812-0000-1000-8000-00805f9b34fb";
        UUID_HID_SERVICE = UUID.fromString(HID_SERVICE);
    }


    public BleServiceV2() {
    }

    @Override
    public void onCreate() {
        super.onCreate();
        mAppContext = this.getApplicationContext();
        mHandler = new ServiceHandler();
        mServiceMessenger = new Messenger(mHandler);
        mIrLossyCompression = new IrLossyCompression();

        // Initializes a Bluetooth adapter.  For API level 18 and above, get a reference to
        // BluetoothAdapter through BluetoothManager.
        final BluetoothManager bluetoothManager =
                (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
        mBluetoothAdapter = bluetoothManager.getAdapter();


    }

    /**
     * 连接到已配对的BLE设备
     *
     * @param deviceName ble设备名称
     * @param deviceAddr ble设备地址
     * @return 返回是否连接上BLE设备
     */
    private boolean connect2BoudedDevice(String deviceName, String deviceAddr) {

        Set devices = this.mBluetoothAdapter.getBondedDevices();
        L.i(TAG, "已连接设备数量:" + devices.size());
        if (devices.size() > 0) {
            Iterator it = devices.iterator();

            BluetoothDevice device;
            String mBluetoothDeviceName;
            String mBluetoothDeviceAddress;
            do {
                if (!it.hasNext()) {
                    return false;
                }

                device = (BluetoothDevice) it.next();
                mBluetoothDeviceName = device.getName();
                mBluetoothDeviceAddress = device.getAddress();
            }
            while ((deviceName != null || deviceAddr != null)
                    && (!mBluetoothDeviceName.equals(deviceName) || deviceAddr != null)
                    && (!mBluetoothDeviceAddress.equals(deviceAddr) || deviceName != null));

            this.mBluetoothDevice = device;
            this.mBluetoothGatt = this.mBluetoothDevice.connectGatt(this, true, mGattCallback);
            L.i(TAG, "发现已配对的蓝牙设备：" + mBluetoothDeviceName);
            return true;
        } else {
            return false;
        }
    }


    //
    private BluetoothGattCallback mGattCallback =
            new BluetoothGattCallback() {

                @Override
                public void onConnectionStateChange(BluetoothGatt gatt, int status,
                                                    int newState) {
                    if (newState == BluetoothProfile.STATE_CONNECTED) {
                        mConnectionState = STATE_CONNECTED;
                        if (gatt != null) {
                            mBluetoothGatt = gatt;
                        }
                        boolean result = mBluetoothGatt.discoverServices();
                        L.i(TAG, "已连接到GATT服务" + (result ? "并开始查找服务" : ",开始查找服务失败"));
                        AppMsg.showToast(mAppContext, "已连接到GATT服务" + (result ? "并开始查找服务" : ",开始查找服务失败"));

                        Message message = Message.obtain();
                        message.what = MSG_GATT_CONNECTED;
                        try {
                            mClientMessenger.send(message);
                        } catch (RemoteException e) {
                            e.printStackTrace();
                        }

                    } else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
                        mConnectionState = STATE_DISCONNECTED;
                        L.i(TAG, "Disconnected from GATT server.");
                        AppMsg.showToast(mAppContext, "GATT服务断开");

                        Message message = Message.obtain();
                        message.what = MSG_GATT_DISCONNECTED;
                        try {
                            mClientMessenger.send(message);
                        } catch (RemoteException e) {
                            e.printStackTrace();
                        }
                    }
                }

                @Override
                // New services discovered
                public void onServicesDiscovered(BluetoothGatt gatt, int status) {

                    if (status == BluetoothGatt.GATT_SUCCESS) {
                        AppMsg.showToast(mAppContext, "发现服务");
                        List<BluetoothGattService> services = gatt.getServices();
                        BluetoothGattService hidService = gatt.getService(UUID_HID_SERVICE);
                        if (hidService != null) {
                            int buzzerService = hidService.getCharacteristics().size();
                            AppMsg.showToast(mAppContext, "发现服务：size=" + buzzerService);
                            L.i(TAG, "Gatt Character Size:" + buzzerService);
                            if (hidService.getCharacteristics().size() > 7) {
                                int CharSize = hidService.getCharacteristics().size();
                                //BluetoothLeBroadcast("nanoic.bluetoothle.service.BROADCAST_ACTION_BLUETOOTH", "nanoic.bluetoothle.service.BROADCAST_CONTENT_GATT_DISCOVERED");
                                List hidCharList = hidService.getCharacteristics();
                                mKeyInCharacteristic = (BluetoothGattCharacteristic) hidCharList.get(6);
                                L.i(TAG, "Vendor In Characteristic:" + mKeyInCharacteristic.toString());
                                L.i(TAG, "Vendor In Descriptors:" + mKeyInCharacteristic.getDescriptors().size());
                                mOtaInCharacteristic = (BluetoothGattCharacteristic) hidCharList.get(CharSize - 1);
                                L.i(TAG, "Vendor In Characteristic:" + mOtaInCharacteristic.toString());
                                L.i(TAG, "Vendor In Descriptors:" + mOtaInCharacteristic.getDescriptors().size());
                                mVendorOutCharacteristic = (BluetoothGattCharacteristic) hidCharList.get(CharSize - 2);
                                L.i(TAG, "Vendor Out Characteristic:" + mVendorOutCharacteristic.toString());
                                L.i(TAG, "Vendor Out Descriptors:" + mVendorOutCharacteristic.getDescriptors().size());
                                mVendorInCharacteristic = (BluetoothGattCharacteristic) hidCharList.get(CharSize - 3);
                                L.i(TAG, "Vendor In Characteristic:" + mVendorInCharacteristic.toString());
                                L.i(TAG, "Vendor In Descriptors:" + mVendorInCharacteristic.getDescriptors().size());
                                mIrOutCharacteristic = (BluetoothGattCharacteristic) hidCharList.get(CharSize - 4);
                                L.i(TAG, "Ir Out Characteristic:" + mIrOutCharacteristic.toString());
                                L.i(TAG, "Ir Out Descriptors:" + mIrOutCharacteristic.getDescriptors().size());
                                mIrInCharacteristic = (BluetoothGattCharacteristic) hidCharList.get(CharSize - 5);
                                L.i(TAG, "Vendor In Characteristic:" + mIrInCharacteristic.toString());
                                L.i(TAG, "Vendor In Descriptors:" + mIrInCharacteristic.getDescriptors().size());


                                setBleNotification();
                                /**
                                 * 已找到服务
                                 */
                                Message message = Message.obtain();
                                message.what = MSG_GATT_SERVICE_DISCOVERD;
                                try {
                                    mClientMessenger.send(message);
                                } catch (RemoteException e) {
                                    e.printStackTrace();
                                }
                            }
                        } else {
                            L.i(TAG, "BluetoothGattService is null");
                            AppMsg.showToast(mAppContext, "BluetoothGattService is null");
                        }

                        BluetoothGattService buzzerGattService = gatt.getService(UUID_BUZZER_SERVICE);
                        if (buzzerGattService != null) {
                            mBuzzerCharacteristic = buzzerGattService.getCharacteristic(UUID_BUZZER_CHARACTER);
                        }
                    } else {
                        L.w(TAG, "onServicesDiscovered received: " + status);
                        AppMsg.showToast(mAppContext, "未发现服务");
                    }

                }

                @Override
                public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
                    String characterUuid = characteristic.getUuid().toString().trim();
                    if ("00002a4d-0000-1000-8000-00805f9b34fb".equals(characterUuid)) {
                        if (characteristic.getValue().length == 8) {
                            L.i(TAG, "onCharacteristicChanged key:" + IrParser.getByteString(characteristic.getValue(), 4));
                        } else {
                            byte[] buff = characteristic.getValue();
                            if (buff[0] == 112) {
                                L.i(TAG, "onCharacteristicChanged IR:" + IrParser.getByteString(characteristic.getValue(), 4));
                                onIrReceived(buff);
                            } else {
                                L.i(TAG, "onCharacteristicChanged Vendor:" + IrParser.getByteString(characteristic.getValue(), 4));
                            }
                        }
                    }

                    super.onCharacteristicChanged(gatt, characteristic);
                }

                @Override
                // Result of a characteristic read operation
                public void onCharacteristicRead(BluetoothGatt gatt,
                                                 BluetoothGattCharacteristic characteristic,
                                                 int status) {
                    if (status == BluetoothGatt.GATT_SUCCESS) {
                        //broadcastUpdate(ACTION_DATA_AVAILABLE, characteristic);
                        AppMsg.showToast(mAppContext, "读数据：" + characteristic);
                    }
                    AppMsg.showToast(mAppContext, "读数据：" + characteristic);
                }

                @Override
                public void onDescriptorWrite(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) {
                    super.onDescriptorWrite(gatt, descriptor, status);
                    AppMsg.showToast(mAppContext, "写数据：" + descriptor.getCharacteristic().toString());
                    AppMsg.showToast(mAppContext, "写数据：" + descriptor.getCharacteristic().toString());
                }

                @Override
                public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {

                    if (characteristic.getUuid().toString().equals("00002a4d-0000-1000-8000-00805f9b34fb")) {
                        byte[] characterValue = characteristic.getValue();
                        if (characterValue[0] == 113) {
                            onIrSend(characterValue);
                        }
                    }
                    super.onCharacteristicWrite(gatt, characteristic, status);
                }

                @Override
                public void onDescriptorRead(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) {
                    AppMsg.showToast(mAppContext, "onDescriptorRead");
                    super.onDescriptorRead(gatt, descriptor, status);
                }

                @Override
                public void onReliableWriteCompleted(BluetoothGatt gatt, int status) {
                    AppMsg.showToast(mAppContext, "onReliableWriteCompleted");
                    super.onReliableWriteCompleted(gatt, status);
                }

                @Override
                public void onReadRemoteRssi(BluetoothGatt gatt, int rssi, int status) {
                    AppMsg.showToast(mAppContext, "onReadRemoteRssi");
                    super.onReadRemoteRssi(gatt, rssi, status);
                }

                @Override
                public void onMtuChanged(BluetoothGatt gatt, int mtu, int status) {
                    AppMsg.showToast(mAppContext, "onMtuChanged");
                    super.onMtuChanged(gatt, mtu, status);
                }
            };


    /**
     * 重置状态，发送下一段红外码Bytes数组
     */
    public void clearFlag2Continue() {
        this.mIrPacketSendOk = false;
        this.mIrPacketRecOk = false;
    }

    /**
     * 重置状态，以发送下一条红外码二维Byte数组
     */
    public boolean clearFlagsToSend() {
        this.mIrPacketSendOk = true;
        this.mIrPacketRecOk = true;
        this.mSendedPacketNum = 0;
        return true;
    }

    /**
     * 接收到外设的反馈
     *
     * @param buf 从Characteristic 中获取的反馈value
     */
    private void onIrReceived(byte[] buf) {
        if (buf[0] == 112) {
            this.mIrPacketRecOk = true;
        }
    }

    /**
     * 接收到外设的反馈
     *
     * @param buf onCharacteristicWrite触发时，即调用ble写数据触发的回调时 Characteristic 中的value
     */
    private void onIrSend(byte[] buf) {
        if (buf[0] == 113 && buf[1] == this.mIrSendBuff[1] && buf[2] == this.mIrSendBuff[2]) {
            this.mIrPacketSendOk = true;
        }

    }

    /**
     * 向mIrOutCharacteristic中写一组数据
     *
     * @param irData 红外数据
     */
    private boolean sendIrData(byte[] irData) {

        if (irData != null && irData.length > 0 && irData.length < 21 && mIrOutCharacteristic != null) {
            mIrOutCharacteristic.setValue(irData);

            return mBluetoothGatt.writeCharacteristic(mIrOutCharacteristic);
        }
        return false;
    }

    private synchronized void sendBleIRData(final BleIRData bleIRData) {
        new Thread() {
            @Override
            public void run() {
                if (!isReady2Send()) {
                    return;
                }

                if (bleIRData.getMode() == BleIRData.MODE_STR) {
                    byte[][] bytes = IrParser.parseRawIrData(bleIRData.getPulse(), bleIRData.getFreq(), 0);
                    long start = System.currentTimeMillis();

                    boolean result = sendIRData(bytes);
                    long end = System.currentTimeMillis();
                    bleIRData.setDuration(end - start);
                    bleIRData.setSendSuccess(result);
                    if (!result) {
                        bleIRData.setErrCode(BleIRData.ERR_UNKNOW);
                    }
                    sendIrFeedback(bleIRData);
                    L.w(TAG, "红外发送 " + (result ? "成功" : "失败") + "!耗时：" + (end - start) + "ms");

                } else if (bleIRData.getMode() == BleIRData.MODE_LIST) {
                    List<String> irDataList = bleIRData.getIrDataList();
                    long start = System.currentTimeMillis();
                    ///////////////////////////////////////////////////////


                    byte[][] bytes = IrParser.getCombinedIrData(irDataList);
                    boolean result = sendIRData(bytes);
                    long end = System.currentTimeMillis();
                    bleIRData.setDuration(end - start);
                    bleIRData.setSendSuccess(result);
                    if (!result) {
                        bleIRData.setErrCode(BleIRData.ERR_UNKNOW);
                    }
                    sendIrFeedback(bleIRData);
                    L.w(TAG, "红外发送 " + (result ? "成功" : "失败") + "!耗时：" + (end - start) + "ms");


                    ///////////////////////////////////////////////////////
                   /* for (String irData : irDataList) {
                        byte[][] bytes = IrParser.parseRawIrData(irData, bleIRData.getFreq(), 0);
                        boolean result = sendIRData(bytes);
                        if (result) {

                            if (!(irDataList.indexOf(irData) == irDataList.size() - 1)) {
                                //没有发送完毕
                                try {
                                    Thread.sleep(bleIRData.getDelay());
                                } catch (InterruptedException e) {
                                    e.printStackTrace();
                                }
                            } else {
                                //发送完毕，该条红外数据发送成功！
                                long duration = System.currentTimeMillis() - start;
                                bleIRData.setSendSuccess(true);
                                bleIRData.setDuration(duration);
                                sendIrFeedback(bleIRData);
                                L.w(TAG, "所有红外发送 成功!耗时：" + duration + "ms");
                                return;
                            }
                        } else {

                            long duration = System.currentTimeMillis() - start;
                            bleIRData.setSendSuccess(false);
                            bleIRData.setErrCode(BleIRData.ERR_UNKNOW);
                            bleIRData.setDuration(duration);
                            sendIrFeedback(bleIRData);
                            L.w(TAG, "红外发送失败!耗时：" + duration + "ms");

                            break;
                        }
                    }*/
                }

            }
        }.start();
    }


    private void sendIrFeedback(BleIRData bleIRData) {


        Message bindResult = Message.obtain();
        bindResult.what = BleServiceV2.MSG_IR_SEND_FEEDBACK;
        bindResult.obj = bleIRData;
        try {
            mClientMessenger.send(bindResult);
        } catch (RemoteException e) {
            e.printStackTrace();
        }

    }

    private synchronized void sendIrData(final BleIRData bleIRData) {
        new Thread() {
            @Override
            public void run() {
                if (!isReady2Send()) {
                    return;
                }

                if (bleIRData.getMode() == BleIRData.MODE_STR) {


                    long start = System.currentTimeMillis();
                    byte[] data = IrParser.parseRawIrData(bleIRData.getPulse(), 0);

                    boolean result = sendIR(data, bleIRData.isNeedCompression());

                    long end = System.currentTimeMillis();
                    bleIRData.setDuration(end - start);
                    bleIRData.setSendSuccess(result);
                    if (!result) {
                        bleIRData.setErrCode(BleIRData.ERR_UNKNOW);
                    }
                    sendIrFeedback(bleIRData);
                    L.w(TAG, "红外发送 " + (result ? "成功" : "失败") + "!耗时：" + (end - start) + "ms");
                } else if (bleIRData.getMode() == BleIRData.MODE_LIST) {
                    long start = System.currentTimeMillis();
                    List<String> irDataList = bleIRData.getIrDataList();
                    for (String irData : irDataList) {
                        byte[] data = IrParser.parseRawIrData(irData, 0);
                        boolean result = sendIR(data, bleIRData.isNeedCompression());
                        if (result) {

                            if (!(irDataList.indexOf(irData) == irDataList.size() - 1)) {
                                //没有发送完毕
                                try {
                                    Thread.sleep(bleIRData.getDelay());
                                } catch (InterruptedException e) {
                                    e.printStackTrace();
                                }
                            } else {
                                //发送完毕，该条红外数据发送成功！
                                long duration = System.currentTimeMillis() - start;
                                bleIRData.setSendSuccess(true);
                                bleIRData.setDuration(duration);
                                sendIrFeedback(bleIRData);
                                L.w(TAG, "所有红外发送 成功!耗时：" + duration + "ms");
                                return;
                            }
                        } else {
                            long duration = System.currentTimeMillis() - start;
                            bleIRData.setSendSuccess(false);
                            bleIRData.setErrCode(BleIRData.ERR_UNKNOW);
                            bleIRData.setDuration(duration);
                            sendIrFeedback(bleIRData);
                            L.w(TAG, "红外发送失败!耗时：" + duration + "ms");
                            break;
                        }
                    }
                }

            }
        }.start();


    }


    @Override
    public IBinder onBind(Intent intent) {
        // TODO: Return the communication channel to the service.
        return mServiceMessenger.getBinder();
    }

    private class ServiceHandler extends Handler {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case MSG_SERVICE_CONNECTED:
                    mClientMessenger = msg.replyTo;
                    L.e(TAG, "client binded!");
                    try {
                        Thread.sleep(3000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    break;
                case MSG_CONNECT2_BLE_DEVICE:
                    boolean result = connect2BoudedDevice(null, null);
                    Message bindResult = Message.obtain();
                    bindResult.what = BleServiceV2.MSG_DEVICE_CONNECTION_RESULT;
                    bindResult.obj = result;
                    try {
                        mClientMessenger.send(bindResult);
                    } catch (RemoteException e) {
                        e.printStackTrace();
                    }

                    break;
                case MSG_SEND_IR_DATA:
                    BleIRData bleIRData = (BleIRData) msg.obj;
                    if (bleIRData.getParseMode() == BleIRData.PARSE_MODE_SELF) {
                        sendBleIRData(bleIRData);
                    } else {
                        sendIrData(bleIRData);
                    }


                    break;
                case MSG_4:
                    break;
                default:
                    super.handleMessage(msg);
                    break;
            }

        }
    }

    /**
     * @param waveBuf         红外波形码
     * @param needCompression 是否压缩
     * @return 发送结果
     */
    public boolean sendIR(byte[] waveBuf, boolean needCompression) {

        if (this.mIrOutCharacteristic != null && this.mIrInCharacteristic != null
                && this.mBluetoothDevice != null && waveBuf.length > 6
                && waveBuf[0] == 120 && waveBuf[1] == 86 && waveBuf[2] == 52) {

            byte[] encWaveBuf = mIrLossyCompression.getIrEncoderFrame(waveBuf);

            IrDataConversion irDataConversion = new IrDataConversion();
            if (encWaveBuf != null && encWaveBuf.length < waveBuf.length && needCompression) {
                L.i(TAG, "Ir Lossy Compress data:" + IrParser.getByteString(encWaveBuf, encWaveBuf.length));
                irDataConversion.fillLossyCompressionIrDataBuf(encWaveBuf);
                this.clearFlagsToSend();
                return sendLossyCompressionWave(irDataConversion);
            } else {
                irDataConversion.fillIrRawDataBuf(waveBuf);
                clearFlagsToSend();
                return sendSourceWaveProcess(irDataConversion);
            }

        } else {
            return false;
        }
    }

    /**
     * 发送红外码
     *
     * @return 发送结果
     */
    private boolean sendIRData(byte[][] irBytes) {
        clearFlagsToSend();
        while (true) {
            if (this.mIrPacketSendOk && this.mIrPacketRecOk) {

                if (mSendedPacketNum == irBytes.length) {
                    //发送完成，返回结果;
                    this.clearFlagsToSend();
                    return true;
                }

                this.mIrSendBuff = irBytes[mSendedPacketNum];

                this.clearFlag2Continue();

                if (!sendIrData(mIrSendBuff)) {
                    return false;
                }

                L.i(TAG, "Send IR data:" + IrParser.getByteString(this.mIrSendBuff, 10));
                ++this.mSendedPacketNum;
            }
        }
    }

    /**
     * 发送压缩的红外码
     *
     * @param waveFormat waveFormat
     * @return 发送结果
     */
    private boolean sendLossyCompressionWave(IrDataConversion waveFormat) {
        while (true) {
            if (this.mIrPacketSendOk && this.mIrPacketRecOk) {
                this.mIrSendBuff = waveFormat.getIrLossyCompressionDataBufPacket(mSendedPacketNum);
                if (this.mIrSendBuff == null) {
                    //发送完成，返回结果;
                    this.clearFlagsToSend();
                    return true;
                }

                this.clearFlag2Continue();

                if (!sendIrData(mIrSendBuff)) {
                    return false;
                }

                L.i(TAG, "Send IR data:" + IrParser.getByteString(this.mIrSendBuff, 10));
                ++this.mSendedPacketNum;
            }
        }
    }


    /**
     * 发送未压缩的红外码
     *
     * @param waveFormat waveFormat
     * @return 发送结果
     */
    private boolean sendSourceWaveProcess(IrDataConversion waveFormat) {

        while (true) {
            if (this.mIrPacketSendOk && this.mIrPacketRecOk) {
                this.mIrSendBuff = waveFormat.getIrRawDataBufPacket(mSendedPacketNum);
                if (this.mIrSendBuff == null) {
                    this.clearFlagsToSend();
                    //所有数据包发送成功
                    return true;
                }

                this.clearFlag2Continue();
                if (!sendIrData(mIrSendBuff)) {
                    return false;
                }

                L.i(TAG, "Send IR data:" + IrParser.getByteString(this.mIrSendBuff, 10));
                ++this.mSendedPacketNum;
            }

        }
    }


    private void setBleNotification() {
        if (mIrInCharacteristic != null) {
            setCharacteristicNotification(mIrInCharacteristic, null, true);
        }
        if (mKeyInCharacteristic != null) {
            setCharacteristicNotification(mKeyInCharacteristic, null, true);
        }

        if (mVendorInCharacteristic != null) {
            setCharacteristicNotification(mVendorInCharacteristic, null, true);
        }

        if (mIrOutCharacteristic != null) {
            setCharacteristicNotification(mIrOutCharacteristic, null, true);
        }
    }

    private boolean setCharacteristicNotification(BluetoothGattCharacteristic characteristic, BluetoothGattDescriptor clientConfig, boolean enable) {
        if (!this.checkGatt()) {
            return false;
        } else {
            boolean ok = false;
            if (this.mBluetoothGatt.setCharacteristicNotification(characteristic, enable) && clientConfig != null) {
                if (enable) {
                    ok = clientConfig.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
                } else {
                    ok = clientConfig.setValue(BluetoothGattDescriptor.DISABLE_NOTIFICATION_VALUE);
                }

                if (ok) {
                    ok = this.mBluetoothGatt.writeDescriptor(clientConfig);
                }
            }

            return ok;
        }
    }

    private boolean checkGatt() {
        return this.mBluetoothAdapter != null && this.mBluetoothGatt != null;
    }

    private boolean isReady2Send() {
        return this.mBluetoothAdapter != null && this.mBluetoothGatt != null && mIrOutCharacteristic != null;
    }


    /**
     *
     *
     *
     */

    @Override
    public boolean onUnbind(Intent intent) {
        // After using a given device, you should make sure that BluetoothGatt.close() is called
        // such that resources are cleaned up properly.  In this particular example, close() is
        // invoked when the UI is disconnected from the Service.
        close();
        return super.onUnbind(intent);
    }

    private void close() {
        if (mBluetoothGatt == null) {
            return;
        }
        mBluetoothGatt.close();
        mBluetoothGatt = null;
    }


}
